package com.mti.zhpt.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mti.zhpt.dao.*;
import com.mti.zhpt.dto.SubsidiaryFeedback;
import com.mti.zhpt.model.Dictionary;
import com.mti.zhpt.model.*;
import com.mti.zhpt.shared.websocket.EventWebSocket;
import com.mti.zhpt.shared.websocket.WSCustomServer;
import com.mti.zhpt.utils.BusinessException;
import com.mti.zhpt.utils.Constant;
import com.mti.zhpt.utils.KeyWorker;
import com.mti.zhpt.utils.SnowFlake;
import com.mti.zhpt.vo.EventReserveVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 预案指挥
 * @Author: zhaopf@mti-sh.cn
 * @Date: 2019/4/22 17:17
 */
@Service("commandReserveServiceImpl")
@Slf4j
public class CommandReserveServiceImpl {

    @Autowired
    private SnowFlake snowFlake;

    @Autowired
    private CommandReserveMapper commandReserveMapper;
    @Autowired
    private CommandReserveCommandMapper commandReserveCommandMapper;
    @Autowired
    private EventMapper eventMapper;
    @Autowired
    private EventPowerMapper eventPowerMapper;
    @Autowired
    private EventDetailsTimerMapper eventDetailsTimerMapper;
    @Autowired
    public EventDetailsMapper eventDetailsMapper;
    @Autowired
    public OrgMapper orgMapper;
    @Autowired
    RequestLeaderMapper requestLeaderMapper;

    @Autowired
    private CommandReserveDetailMapper reserveDetailMapper;

    @Autowired
    private RequestLeaderServiceImpl requestLeaderService;

    @Autowired
    EventInstructionFeedBackMapper eventInstructionFeedBackMapper;

    @Autowired
    EventServiceImpl eventService;

    @Autowired
    DictionaryServiceImpl dictionaryService;

    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public PageInfo queryAll(String event_id, String param,String ssxqPrefix,Integer page,Integer pageSize) {
        EventEntity entity = eventMapper.getByEventId(event_id);
        PageHelper.startPage(page, pageSize);
        List<Map<String,Object>> entityList = commandReserveMapper.queryAll(event_id, param,ssxqPrefix,entity==null?"":entity.getCaseTypeVal(),null,null);
        PageInfo pageInfo = new PageInfo(entityList);
        return pageInfo;
    }

    public Map<Object, Object> queryCommand(EventReserveCommandEntity entity) {
        Map<Object, Object> map = new HashMap<>();
        List<EventReserveCommandEntity> stageType = commandReserveCommandMapper.queryStageType(entity);
        map.put("stageType", stageType);
        List<EventReserveCommandEntity> entityList = commandReserveCommandMapper.queryCommand(entity);
        map.put("entityList", entityList);

        return map;
    }

    public List<Map<Object, Object>> queryCommandModel(String reserve_id) {
        return commandReserveMapper.queryCommandModel(reserve_id);
    }

    /**
     * 启动预案
     *
     * @param event_id   案件id
     * @param reserve_id 预案ID
     * @return
     */
    public Map<Object, Object> doCommandModel(String event_id, String reserve_id) {
        Map<Object, Object> map = new HashMap<>();
        commandReserveMapper.doCommandModel(event_id, reserve_id);
        eventMapper.updateEventReserve(event_id, reserve_id);
        List<Map<Object, Object>> unitTask = commandReserveMapper.queryTaskCommand(event_id);
        map.put("unitTask", unitTask);

        List<Map<Object, Object>> leaderTask = commandReserveMapper.queryTaskLeaderCommand(event_id);
        map.put("leaderTask", leaderTask);

        return map;
    }

    public int cancelCommandModel(String event_id) {
        int result = 0;
        result += eventPowerMapper.delEventPower(event_id);
        result += commandReserveMapper.cancelCommandModelCommandModel(event_id);
        result += eventDetailsTimerMapper.delTimerList(event_id);
        result += requestLeaderMapper.delRequest(event_id);
        result += requestLeaderMapper.delResponse(event_id);
        result += requestLeaderMapper.delResponseRecord(event_id);
        eventMapper.updateEventReserve(event_id, "0");
        return result;
    }

    public List<Map<Object, Object>> taskaddCommand(List<EventTask> eventTasks) {
        EventTask et = eventTasks.get(0);
        for (EventTask eventTask : eventTasks) {
            eventTask.setId(snowFlake.nextId());
            commandReserveMapper.taskaddCommand(eventTask);
        }
        return commandReserveMapper.queryTaskCommand(et.getEvent_id());
    }

    public List<Map<Object, Object>> queryTaskCommand(String event_id) {
        return commandReserveMapper.queryTaskCommand(event_id);
    }

    public List<Map<Object, Object>> doTaskCommand(List<EventTask> eventTasks) {
        log.debug("doTaskCommand!!!!!");
        EventTask et = eventTasks.get(0);
        Date now = new Date();

        boolean isRequestLeader = false;
        List<String> leaders = new ArrayList<>();

        for (EventTask eventTask : eventTasks) {
            eventTask.setDoTime(now);
            // 单位指令
            if (eventTask.getInstructionType().intValue() == 2) {
                // 判断力量表里是否已存在该组织
                int cov = eventPowerMapper.queryOrg(eventTask.getEvent_id(), eventTask.getOrg_id());
                // 参战力量改变
                if (cov == 0) {
                    eventTask.setId(snowFlake.nextId());
                    eventPowerMapper.insertEventPower(eventTask);
                } else {
                    eventPowerMapper.updateEventPower(eventTask);
                }
                Map<String, Object> org = orgMapper.getOrgNameById(eventTask.getOrg_id());
                if (org.containsValue("org_name")) {
                    eventTask.setOrg_name((String) org.get("org_name"));
                }
                if (org.containsValue("org_longitude")) {
                    eventTask.setOrg_longitude((double) org.get("org_longitude"));
                }
                if (org.containsValue("org_latitude")) {
                    eventTask.setOrg_latitude((double) org.get("org_latitude"));
                }
                // 添加事件时间轴
                eventDetailsTimerMapper.insertTimerByEventTask(eventTask);
            } else if (eventTask.getInstructionType().intValue() == 3) { //汇报领导
                leaders.add(eventTask.getLeaderId());
            }

            // 只给警员发socket消息
            Map<String, Object> detailsEntity = eventDetailsMapper.queryDetails(eventTask.getEvent_id());
            List<Map<String, Object>> infolist = new ArrayList<Map<String, Object>>();
            Map<String, Object> reqobj = new HashMap<String, Object>();
            reqobj.put("msgType", Constant.MSG_ORDER);
            reqobj.put("id", Integer.toString(eventTask.getTimer_id()));
            reqobj.put("title", detailsEntity.get("address"));
            reqobj.put("content", eventTask.getRemark());
            reqobj.put("orderType", detailsEntity.get("case_type"));
            reqobj.put("createTime", formatter.format(now));
            reqobj.put("isRead", 1);// 1未读、2已读
            infolist.add(reqobj);
            if (eventTask.getLatitude() == 0 || eventTask.getLongitude() == 0) {
                eventTask.setLongitude((double) detailsEntity.get("longitude"));
                eventTask.setLatitude((double) detailsEntity.get("latitude"));
            }
            eventTask.setMsgType(Constant.MSG_ORDER_ORG);
            try {
                WSCustomServer.sendInfo(infolist, "user");
                EventWebSocket.sendInfo(eventTask);
            } catch (IOException e) {
                log.error("发送指令失败");
                e.printStackTrace();
            }
            if (eventTask.getStage_id() != 0 && eventTask.getId() != null) {
                log.debug("处理来自预案的");
                // 任务状态改变
                commandReserveMapper.taskupdateCommand(eventTask);
            } else {
                log.debug("处理来自精准指挥的");
            }
        }

        // 汇报领导
        if (isRequestLeader) {
            TextRequest request = new TextRequest();
            request.setContent("请示领导");
            request.setEventid(et.getEvent_id());
            request.setReq_way(2);
            request.setCreate_time(now);

            request.setLeaders(leaders);
            requestLeaderService.doRequest(request);
        }

        return commandReserveMapper.queryTaskCommand(et.getEvent_id());
    }

    /**
     * 添加或编辑预案
     *
     * @param eventReserveVo 预案vo
     * @return
     */
    @Transactional
    public int addCommand(EventReserveVo eventReserveVo) {
        int result = 0;
        Date date = new Date();
        if (StringUtils.isBlank(eventReserveVo.getReserveId())) { // 添加
            eventReserveVo.setReserveId(snowFlake.nextId());
            eventReserveVo.setCreateTime(date);
            eventReserveVo.setUpdateTime(date);
            EventReserveEntity eventReserveEntity = new EventReserveEntity();
            BeanUtils.copyProperties(eventReserveVo, eventReserveEntity);
            for (EventReserveDetailEntity eventReserveDetailEntity : eventReserveVo.getEventReserveDetailEntityList()) {
                eventReserveDetailEntity.setId(snowFlake.nextId());
            }
            // 保存预案
            commandReserveMapper.insertReserve(eventReserveEntity);
            // 保存预案详情
            reserveDetailMapper.batchInsertReserveDetail(eventReserveVo.getReserveId(), eventReserveVo.getEventReserveDetailEntityList());
        } else { // 编辑
            //查询所有原有ID
            eventReserveVo.setUpdateTime(date);
            List<EventReserveEntity> reserveEntityList = new ArrayList<>();
            reserveEntityList.add(eventReserveVo);
            commandReserveMapper.batUpdateById(reserveEntityList);
            List<String> oldIds = reserveDetailMapper.queryOldDetailIds(eventReserveVo.getReserveId());
            Set<String> oldSets = new HashSet<>(oldIds);
            Map<String,EventReserveDetailEntity> updateMap = new HashMap<>();
            eventReserveVo
                    .getEventReserveDetailEntityList()
                    .parallelStream()
                    .filter(item->!StringUtils.isEmpty(item.getId()))
                    .forEach(item->updateMap.put(item.getId(),item));
            //从老ID中去除已删除数据
            reserveDetailMapper.removeByDetailIds(oldSets.stream().filter(oid->!updateMap.containsKey(oid)).collect(Collectors.toList()));
            //更新数据
            reserveDetailMapper.batchUpdate(oldSets.stream().filter(updateMap::containsKey).map(updateMap::get).collect(Collectors.toList()));
            //筛选新增数据
            List<EventReserveDetailEntity> insertList = new ArrayList<>();
            eventReserveVo
                    .getEventReserveDetailEntityList()
                    .parallelStream()
                    .filter(item->StringUtils.isEmpty(item.getId()))
                    .forEach(item->{
                        item.setId(KeyWorker.nextId());
                        item.setReserveId(eventReserveVo.getReserveId());
                        insertList.add(item);
                    });
            //插入新增数据
            if(!insertList.isEmpty())
                reserveDetailMapper.insertReserveDetail(insertList);
            // 删除原有预案
//            commandReserveMapper.removeByreserveId(eventReserveVo.getReserveId());
        }
        result = 1;

        return result;

    }

    /**
     * 根据预案id查询预案信息
     *
     * @param reserveId 预案id
     * @return
     */
    public EventReserveVo getByReserveId(String reserveId) {
        EventReserveVo eventReserveVo = new EventReserveVo();

        EventReserveEntity eventReserveEntity = commandReserveMapper.getById(reserveId);
        if (null == eventReserveEntity) {
            throw new BusinessException(500, "当前预案不存在，请输入正确预案id");
        }

        BeanUtils.copyProperties(eventReserveEntity, eventReserveVo);

        List<EventReserveDetailEntity> eventReserveDetailEntities = reserveDetailMapper.listByReserveId(reserveId);

        eventReserveVo.setEventReserveDetailEntityList(eventReserveDetailEntities);

        return eventReserveVo;
    }

    /**
     * 分页查询预案
     *
     * @param event_id 预案id
     * @param param    参数
     * @param page     当前页
     * @param pageSize 每页显示条数
     * @return
     */
    public PageInfo pageByReserve(String event_id, String param, Integer page, Integer pageSize) {
        PageHelper.startPage(page, pageSize);
        EventEntity entity = eventMapper.getByEventId(event_id);
        //案由
        List<Map<String,Object>> finalList = new ArrayList<>();
        if(entity!=null){
            /**
             * 匹配所有与event案由相同的预案
             */
            String cType = entity.getCaseTypeVal();
            List<Map<String,Object>> entityList = commandReserveMapper.queryAll(event_id, param,null,cType,1,StringUtils.isEmpty(entity.getLevel())?null:entity.getLevel());
            //查找关键字匹配的数据
            List<Map<String,Object>> filterList = commandReserveMapper.selectAll(event_id,StringUtils.isEmpty(entity.getLevel())?null:entity.getLevel());
            filterList = filterList.parallelStream()
                    .filter(e->e.getOrDefault("keyword","")!=null && !StringUtils.isEmpty(e.getOrDefault("keyword","").toString())).filter(e->{
                String[] keys = e.getOrDefault("keyword","").toString().split(",");
                return Arrays.stream(keys).anyMatch(k -> (entity.getAddress() != null && entity.getAddress().contains(k)) || (entity.getContent() != null && entity.getContent().contains(k)));
            }).collect(Collectors.toList());
            Set<String> filter = new HashSet<>();
            entityList.forEach(e->{
                if(!StringUtils.isEmpty(param)){
                    StringBuilder sb = new StringBuilder();
                    sb.append(e.getOrDefault("reservename","").toString()).append(",").append(e.getOrDefault("keyword","").toString()).append(",").append(e.getOrDefault("casetype","").toString());
                    if(filter.add(e.getOrDefault("reserveid","").toString()) && sb.toString().contains(param)){
                        finalList.add(e);
                    }
                }else{
                    if(filter.add(e.getOrDefault("reserveid","").toString())){
                        finalList.add(e);
                    }
                }
            });
            filterList.forEach(e->{
                if(!StringUtils.isEmpty(param)){
                    StringBuilder sb = new StringBuilder();
                    sb.append(e.getOrDefault("reservename","").toString()).append(",").append(e.getOrDefault("keyword","").toString()).append(",").append(e.getOrDefault("casetype","").toString());
                    if(filter.add(e.getOrDefault("reserveid","").toString()) && sb.toString().contains(param)){
                        finalList.add(e);
                    }
                }else{
                    if(filter.add(e.getOrDefault("reserveid","").toString())){
                        finalList.add(e);
                    }
                }
            });
        }
        if(finalList.isEmpty())
            return new PageInfo(commandReserveMapper.queryAll(event_id, null,null,null,null,null));
        else
            return new PageInfo(finalList);
    }

    /**
     * 查询下达的指令
     *
     * @param eventId 案件id
     * @return
     */
    public Map<Object, Object> queryTaskByeventId(String eventId, String send_orgId) {
        Map<Object, Object> map = null;
        try {
            map = new HashMap<>();
            List<Map<Object, Object>> unitTask = commandReserveMapper.queryTaskCommandUnit(eventId, send_orgId,null);
            for (int i = 0; i < unitTask.size(); i++) {
                List<Map<Object, Object>> tasks = (List<Map<Object, Object>>) unitTask.get(i).get("tasks");
                for (int y = 0; y < tasks.size(); y++) {
                    Map<Object, Object> taskMap = tasks.get(y);
                    List<Map<Object, Object>> ResponseTask = commandReserveMapper.queryResponse((String) taskMap.get("id"));
                    taskMap.put("responseTask", ResponseTask);
                }

            }
            map.put("unitTask", unitTask);
        } catch (Exception e) {
            log.error("查询下达的指令错误：", e);
        }
        return map;
    }

    /**
     * 查询接收的指令
     *
     * @param policeId 警员id
     * @param orgId    机构id
     * @param eventId
     * @return
     */
    public Map<Object, Object> receiveTask(String policeId, String orgId, String eventId) {
        Map<Object, Object> map = null;
        try {
            map = new HashMap<>();
            List<Map<Object, Object>> unitTask = commandReserveMapper.queryTaskCommandByOrgId(orgId,eventId);
            for (int i = 0; i < unitTask.size(); i++) {
                List<Map<Object, Object>> tasks = (List<Map<Object, Object>>) unitTask.get(i).get("tasks");
                for (int y = 0; y < tasks.size(); y++) {
                    Map<Object, Object> taskMap = tasks.get(y);
                    List<Map<Object, Object>> ResponseTask = commandReserveMapper.queryResponse((String) taskMap.get("id"));
                    taskMap.put("responseTask", ResponseTask);
                }

            }
            map.put("unitTask", unitTask);
        } catch (Exception e) {
            log.error("查询接收的指令：", e);
        }

        return map;
    }

    /**
     * 指令反馈
     *
     * @param instructionFeedbackEntity 指令反馈对象
     * @return
     */
    public boolean instructionFeedback(InstructionFeedbackEntity instructionFeedbackEntity) {

        instructionFeedbackEntity.setId(snowFlake.nextId());
        instructionFeedbackEntity.setCreateTime(new Date());
        boolean result = eventInstructionFeedBackMapper.instructionFeedback(instructionFeedbackEntity);

        return result;
    }

    /**
     * 反馈列表查询
     *
     * @param instructionFeedbackEntity 指令反馈对象
     * @return
     */
    public List<InstructionFeedbackEntity> listByInstructionFeedbackEntity(InstructionFeedbackEntity instructionFeedbackEntity) {

        instructionFeedbackEntity.setId(snowFlake.nextId());
        instructionFeedbackEntity.setCreateTime(new Date());
        List<InstructionFeedbackEntity> instructionFeedbackEntities = eventInstructionFeedBackMapper.listByInstructionFeedbackEntity(instructionFeedbackEntity);

        return instructionFeedbackEntities;
    }

    /**
     * 单位指令监控列表查询
     *
     * @param eventId 案件id
     * @return
     */
    public  List<Map<Object, Object>> listByunitInstructionMonitoring(String eventId) {

        List<Map<Object, Object>> resultList =  new ArrayList<>();
        try {

            List<Map<Object, Object>> deptCodeList = commandReserveMapper.queryDeptCode(eventId);
            for (int z = 0; z < deptCodeList.size(); z++) {
                Map<Object, Object> deptCodeMap = deptCodeList.get(z);
                if (CollectionUtils.isEmpty(deptCodeMap)){
                    continue;
                }
                Map<Object, Object> map = new HashMap<>();
                String org_id = (String) deptCodeMap.get("org_id");
                Map<Object, Object> deptNameMap = commandReserveMapper.queryDeptName(org_id);
                String org_name = (String) deptNameMap.get("org_name");

                List<Map<Object, Object>> unitTask = commandReserveMapper.queryTaskCommandUnit(eventId,null,org_id);
                for (int i = 0; i < unitTask.size(); i++) {
                    Map<Object, Object> unitTaskMap = unitTask.get(i);
                    List<Map<Object, Object>> tasks = (List<Map<Object, Object>>) unitTaskMap.get("tasks");
                    for (int y = 0; y < tasks.size(); y++) {
                        Map<Object, Object> taskMap = tasks.get(y);
                        List<Map<Object, Object>> ResponseTask = commandReserveMapper.queryResponse((String) taskMap.get("id"));
                        taskMap.put("responseTask", ResponseTask);
                    }

                }
                map.put("unitTask", unitTask);
                map.put("deptName", org_name);
                map.put("deptCode", org_id);
                resultList.add(map);
            }

        } catch (Exception e) {
            log.error("查询下达的指令错误：", e);
        }
        return resultList;



//        Map<Object, Object> map = new HashMap<>();
//        List<Map<Object, Object>> unitTask = commandReserveMapper.listByunitInstructionMonitoring(eventId);
//        map.put("unitTask", unitTask);
//
//        return map;
    }

    /**
     * 模拟演练
     *
     * @param reserveId 预案id
     * @return
     */
    public boolean simulationExercise(String reserveId) {

        EventReserveVo eventReserveVo = this.getByReserveId(reserveId);
        if (null == eventReserveVo) {
            throw new BusinessException(500, "当前预案不存在，请输入正确预案id");
        }

        String caseType = "011100";
        String title = "诈骗";
        if (StringUtils.isNotBlank(eventReserveVo.getCaseType())) {
            title = eventReserveVo.getCaseType().split(",")[0];

            String dicType = "ALARM_TYPE_CODE";
            Dictionary dictionary = dictionaryService.getByTypeAndValue(dicType, title);
            if (null != dictionary) {
                caseType = dictionary.getKey();
            }
        }

        // 模拟数据
        EventEntity eventEntity = new EventEntity();
        eventEntity.setPoliceMan("模拟匿名");
        eventEntity.setPhone("13100000000");
        eventEntity.setCaseType(caseType);
        eventEntity.setAddress("模拟地址");
        eventEntity.setContent("2019年1月26日 11时2分0秒 李志远( 13832684717 ) 报警：固安县固马路华联超市 发生一起交通事故 ， 一辆货车与一辆丰田相撞，无人员伤亡");
        eventEntity.setCreateTime(new Date());
        eventEntity.setLongitude(116.7);
        eventEntity.setLatitude(39.5);
        eventEntity.setTested(1);
        eventEntity.setTitle(title);
        eventEntity.setLevel("01");
        eventEntity.setImportantEvent(1);
        eventEntity.setEventType("0");
        eventService.addEventByEventEntity(eventEntity);
        return true;
    }

    public void subsidiaryFeedback(SubsidiaryFeedback subsidiaryFeedback) {
        try {
            subsidiaryFeedback.setCreateTime(new Date());
            subsidiaryFeedback.setId(KeyWorker.nextId());
            commandReserveMapper.subsidiaryFeedback(subsidiaryFeedback);
            subsidiaryFeedback.setFeedback("辅助反馈");
            commandReserveMapper.addEventTimer(subsidiaryFeedback);
            /**
             * 给指令反馈
             * 更新指令状态
             */
            commandReserveMapper.updateTaskStatus(subsidiaryFeedback.getTaskId(), 60);
        } catch (Exception e) {
            log.error("辅助反馈错误", e);
        }
    }

    public void updateTasksStatus(String id, Integer status) {
        if (StringUtils.isEmpty(id) || status == null) {
            throw new com.mti.zhpt.shared.Exception.BusinessException("参数有误");
        }
         commandReserveMapper.updateTaskStatus(id, status);
    }
}
